﻿// =================================================================
//  Copyright (c) "David R. Guindo", Software architect
//  
//  This code is released under the terms of the Apache License, Version 2.0,
//  http://www.apache.org/licenses/LICENSE-2.0
//  
//  THIS CODE AND INFORMATION ARE PROVIDED WITHOUT WARRANTIES,
//  WITHOUT LIMITING COMMERCIAL OR PARTICULAR USE.
// =================================================================

namespace ScreenManager
{
   using System;
   using System.Collections.Generic;
   using System.Globalization;
   using System.Runtime.InteropServices;
   using System.Threading;
   using System.Windows;
   using System.Windows.Controls;
   using System.Windows.Forms;
   using System.Windows.Interop;
   using System.Windows.Media;

   using Application = System.Windows.Application;
   using HorizontalAlignment = System.Windows.HorizontalAlignment;

   public static partial class ScreenManager
   {
      private const int ScMonitorpower = 0xF170;
      private const int WmSyscommand = 0x0112;

      [DllImport("user32")]
      private static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, uint wParam, int lParam);



      /// <summary>
      ///    Shows a white number with black border over 
      ///    each display of the device for the specified time in milliseconds
      /// </summary>
      /// <param name="miliseconds"> The miliseconds for show the numbers. </param>
      public static void Identify(int miliseconds)
      {
         var openedWindows = new List<Window>();

         for (int i = 0; i < Screen.AllScreens.Length; i++)
         {
            Screen screen = Screen.AllScreens[i];

            var window = CreateIdentifiedWindow(screen, i);

            window.Show();
            openedWindows.Add(window);
         }

         Thread.Sleep(miliseconds);

         foreach (Window w in openedWindows)
         {
            w.Close();
         }
      }

      /// <summary>
      /// Set monitors to Low energy mode. 
      /// WARNING: ONLY IF MONITOR SUPPORTS.
      /// </summary>
      public static void TurnEnergySaver()
      {
         var window = Application.Current.MainWindow ?? new Window();

         if (window != null)
         {
            HwndSource source = PresentationSource.FromVisual(window) as HwndSource;
            if (source != null)
            {
               SendMessage(source.Handle, WmSyscommand, ScMonitorpower, 1);
            }
         }
      }

      /// <summary>
      ///    Turns the off.
      /// </summary>
      public static void TurnOff()
      {
         if (Application.Current.MainWindow != null)
         {
            var source = PresentationSource.FromVisual(Application.Current.MainWindow) as HwndSource;
            if (source != null)
            {
               SendMessage(source.Handle, WmSyscommand, ScMonitorpower, 2);
            }
         }
      }

      /// <summary>
      ///    Turns the on.
      /// </summary>
      public static void TurnOn()
      {
         var window = Application.Current.MainWindow ?? new Window();

         if (window != null)
         {
            var source = PresentationSource.FromVisual(window) as HwndSource;
            if (source != null)
            {
               SendMessage(source.Handle, WmSyscommand, ScMonitorpower, -1);
            }
         }
      }

      /// <summary>
      ///    Creates a window identified with the specified number.
      /// </summary>
      /// <param name="screen"> The screen. </param>
      /// <param name="identifier"> The screen identifier. </param>
      /// <returns> </returns>
      private static Window CreateIdentifiedWindow(Screen screen, int identifier)
      {
         var grid = new Grid();
         var window = new Window
            {
               WindowStartupLocation = WindowStartupLocation.Manual,
               Content = grid,
               AllowsTransparency = true,
               WindowStyle = WindowStyle.None,
               Left = screen.WorkingArea.Left,
               Top = screen.WorkingArea.Top,
               Width = screen.WorkingArea.Width,
               Height = screen.WorkingArea.Height,
               Background = Brushes.Transparent,
               ResizeMode = ResizeMode.NoResize,
               ShowInTaskbar = false,
               Topmost = true
               //, WindowState = WindowState.Minimized;
            };

         var tb0 = new TextBlock
            {
               Margin = new Thickness(-3, -1, -1, -1),
               FontSize = 184,
               FontFamily = new FontFamily("Arial Black"),
               Foreground = Brushes.Black,
               FontWeight = FontWeights.ExtraBold,
               VerticalAlignment = VerticalAlignment.Center,
               HorizontalAlignment = HorizontalAlignment.Center
            };

         var tb = new TextBlock
            {
               Text = identifier.ToString(CultureInfo.InvariantCulture),
               FontSize = 180,
               FontFamily = new FontFamily("Arial Black"),
               Foreground = Brushes.GhostWhite,
               FontWeight = FontWeights.DemiBold,
               VerticalAlignment = VerticalAlignment.Center,
               HorizontalAlignment = HorizontalAlignment.Center
            };

         tb0.Text = tb.Text;
         grid.Children.Add(tb0);
         grid.Children.Add(tb);
         return window;
      }
   }
}